-
Notifications
You must be signed in to change notification settings - Fork 420
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add correct column metadata to all warning checks #1127
Add correct column metadata to all warning checks #1127
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking great. Just a minor nitpick and we have to find out why the column info seems to be off for Elixir versions 1.11 and 1.12 ...
end | ||
|
||
defp get_forbidden_call(ast, acc) do | ||
{ast, acc} | ||
end | ||
|
||
defp issues_for_call(attribute, {call, trigger}, meta, issue_meta, issues) do | ||
defp issues_for_call(attribute, {call_meta, call, trigger}, _meta, issue_meta, issues) do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we are ignoring _meta
, we should probably not pass it on line 45.
So diffing elixir 1.13 and 1.12 doesn't reveal at first glance what changed between the two versions.
|
Yeah. I just pushed some "checks" to the testing pipeline that make sure the trigger, line and column info is actually consisistent. Could you rebase against |
b1ef181
to
47b2000
Compare
Okay, so the new pipeline is showing some deeper issues: https://github.com/rrrene/credo/actions/runs/8901349869/job/24445604486?pr=1127 We have to provide an accurate |
Hmm I don't think I've touched any of the trigger code, I'll take a look tomorrow morning |
I probably did not phrase that in a good way, apologies. The This PR wants to fix instances where the But we cannot pick the What I meant with my last comment is that it is not an option to change the trigger from ":os.cmd" to "cmd", because that would potentially break backwards compatibility and the intent of the check in question. |
Maybe in this case I could get the module name and calculate it's string length and remove that from the column length to fix it, but it still doesn't cover the case where the AST is off by 1 on older versions of Elixir. |
Let's ignore the off-by-one thing for Elixir 1.11 and 1.12 for now (I can deal with that after merging). Our main focus should be to get the correct column for the existing trigger, as that is the primary improvement this PR brings 👍 |
Hey I fixed the Erlang stdlib function columns by just calculating the string length of the module. Also fixed some of the triggers that were producing warnings to match the real trigger. Do you have any suggestions on how to fix the other 3 triggers that mismatch the actual code and column that are producing the warnings in the tests:
So the last 2 can maybe be left as is. The empty enum check I've left it to follow the operator semantics above, but am open to changing. |
What do you mean? We can not include a wrong In your first example, the trigger is actually In the second example, of course the problem is the metadata entry in the keyword list (named Of course, in the special case with the grouped aliases for the Forbidden Module check, the |
Hey 👋 Decided to revert the column info for the missing metadata key in the Logger config since it's not so trivial to calculate the right column info for the starting position of the key in question. Maybe I could do it in a separate PR by using Macro.to_string instead of doing it by hand on the AST. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are getting there. With one or two of the "non-necessary refactorings" I am afraid that this PR got worse, so let's discuss/revert 👍
@@ -27,28 +27,37 @@ defmodule Credo.Check.Warning.LeakyEnvironment do | |||
Credo.Code.prewalk(source_file, &traverse(&1, &2, issue_meta)) | |||
end | |||
|
|||
@offset 2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's give this a less confusing name: @colon_and_dot_length
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I saw that there's a backports module, should I move the attribute there as a function and compile a different version for the older elixir versions to make the tests pass?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I mentioned I will deal with that later. Especially because it won't be a problem for long, since we can stop supporting 1.12 as soon as Elixir 1.17 drops.
Enum.map(modules, fn key -> {Name.full(key), nil} end) | ||
Map.new(modules, fn module -> | ||
full = Name.full(module) | ||
{full, "The `#{Name.full(module)}` module is not allowed."} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did you choose to put the fallback message here instead of where it was? To me seems unclear.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm I did it because issue_for was getting too many arguments since I would need the trigger to be the short name in some cases, and then I'd need to pass in the full name as well in this scenario. I can revert it though
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can tolerate 5, 6 or even 7 arguments in a function in functional programming 🙂
Especially if it makes the flow & origin of information more clear.
|
||
defp issue_for(issue_meta, meta, trigger, message) do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again: Why the refactor to get the message (and trigger) as an argument instead of looking it up here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The trigger would need to be different if it's coming from a group alias, while the message is always based on the full name so far, since I didn't know if changing the message would be some kind of a compatibility problem decided to keep it consistent as it was. But I don't mind reworking it like this if you prefer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the trigger is different for different scenarios, we can pass it in.
# offset 2 characters for the dot call and the atom syntax | ||
@offset 2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above: please rename and delete the comment explaining the name
""" | ||
|> to_source_file | ||
|> run_check(@described_check) | ||
|> assert_issues(fn [one, two] -> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are these list items named in order here and named in reverse order on many other tests? Please be consistent.
""" | ||
|> to_source_file | ||
|> run_check(@described_check) | ||
|> assert_issues(fn [one, two] -> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above.
Enum.reduce(aliases, issues, fn {:__aliases__, meta, module}, issues -> | ||
full_name = Name.full([base_alias, module]) | ||
|
||
if found_module?(full_name, forbidden_modules) do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this exactly the same as if forbidden_modules[full_name] do
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's an artifact of the map initializing with nil values at first, while is_map_key would return true here.
Reverted the changes on the forbidden module check and just added a trigger as a variable + reduce one pass with enum. |
Thanks for guiding me through ❤️ |
Hey 👋, I was working on next-ls code actions from credo when we noticed that the column information is missing.
This branch is a follow up on #1126. The main use case is generating a correct code action if there are two warnings on the same line. Without the column information 2 different warnings will map to the same AST when searching for it.
I kinda picked the column arbitrarily, so ping me if we should take it from another AST node, but generally I tried to follow the following rules:
|Enum.count(...)
x |and x
instead of the right/left hand side)erlang.|function
since the AST for theerlang
bit is different and has no column information)